using System;
using System.Collections.ObjectModel;

namespace Controls
{
    /// <summary>
    /// This <see cref="SequenceItem"/> will be loaded asynchronously. Useful when
    /// the loading duration for the associated panel is considerably long.
    /// </summary>
    /// <remarks>This can be used only in the case where the associated panel does not 
    /// use any shared resource top load. For example if the are two panels and 
    /// both need to access some shared resource such as same session value or same 
    /// variable, in that case neither of those two panels can be used with <see cref="AsyncSplitItem"/>.
    /// Only in the panels which can be loaded with atomicity, i.e. with accessing/ sharing
    /// any resource with any other panel, can be used with <see cref="AsyncSplitItem"/>.</remarks>
    public class AsyncSplitItem : SequenceItem
    {
        /// <summary>
        /// Raised when the <see cref="SequenceItem"/> is ready to load tyhe associated panel.
        /// </summary>
        public event EventHandler ItemSequenced;

        /// <summary>
        /// Overriden to invoke the <see cref="ItemSequenced"/> asynchornously.
        /// </summary>
        protected internal override void LoadUpdatePanel(Collection<SequenceItem> inProgressSequenceItems)
        {
            AsyncCallback asyncCallback = OnCallComplete;
            inProgressSequenceItems.Add(this);            
            ItemSequenced.BeginInvoke(this, EventArgs.Empty, asyncCallback, inProgressSequenceItems);
        }

        /// <summary>
        /// Assigned the call complete flag and updates the associated update panel.
        /// </summary>
        /// <param name="asyncResult"></param>
        private void OnCallComplete(IAsyncResult asyncResult)
        {
            UpdatePanel.Update();
            HasLoaded = true;
            ((Collection<SequenceItem>)asyncResult.AsyncState).Remove(this);
        }

        /// <summary>
        /// Overrided to indicate load status for <see cref="AsyncSplitItem"/>.
        /// See <see cref="SequenceItem.HasLoadCompleted"/>.
        /// </summary>
        protected internal override bool HasLoadCompleted()
        {
            return HasLoaded;
        }
    }
}